/*
 * Copyright (c) 2024 Black Sesame Technologies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "dal_fastdds/converter/InstanceHandleConverter.hpp"

const dal_instance_handle_t DAL_HANDLE_NIL = {0, 0, 0, 0};

const uint32_t bit_24 = 24;
const uint32_t bit_16 = 16;
const uint32_t bit_8 = 8;

InstanceHandleConverter* InstanceHandleConverter::singleton_ = nullptr;

InstanceHandleConverter::InstanceHandleConverter() {}

InstanceHandleConverter* InstanceHandleConverter::GetInstance()
{
    if (singleton_ == nullptr) {
        singleton_ = new InstanceHandleConverter();
    }
    return singleton_;
}

dal_ret_t
InstanceHandleConverter::ConvertInstanceHandleFromDalToFastdds(dal_instance_handle_t* d_handle,
                                                               InstanceHandle_t* f_handle)
{
    if (f_handle == nullptr || d_handle == nullptr)
        return DAL_RETCODE_BAD_PARAMETER;
    if (memcmp(d_handle, &DAL_HANDLE_NIL, sizeof(dal_instance_handle_t)) == 0) {
        (*f_handle) = HANDLE_NIL;
        return DAL_RETCODE_OK;
    }
    (f_handle->value)[0] = static_cast<uint8_t>(d_handle->segment_0_);
    (f_handle->value)[1] = static_cast<uint8_t>(d_handle->segment_0_ >> bit_8);
    (f_handle->value)[2] = static_cast<uint8_t>(d_handle->segment_0_ >> bit_16);
    (f_handle->value)[3] = static_cast<uint8_t>(d_handle->segment_0_ >> bit_24);
    (f_handle->value)[4] = static_cast<uint8_t>(d_handle->segment_1_);
    (f_handle->value)[5] = static_cast<uint8_t>(d_handle->segment_1_ >> bit_8);
    (f_handle->value)[6] = static_cast<uint8_t>(d_handle->segment_1_ >> bit_16);
    (f_handle->value)[7] = static_cast<uint8_t>(d_handle->segment_1_ >> bit_24);

    (f_handle->value)[8] = static_cast<uint8_t>(d_handle->segment_2_);
    (f_handle->value)[9] = static_cast<uint8_t>(d_handle->segment_2_ >> bit_8);
    (f_handle->value)[10] = static_cast<uint8_t>(d_handle->segment_2_ >> bit_16);
    (f_handle->value)[11] = static_cast<uint8_t>(d_handle->segment_2_ >> bit_24);
    (f_handle->value)[12] = static_cast<uint8_t>(d_handle->segment_3_);
    (f_handle->value)[13] = static_cast<uint8_t>(d_handle->segment_3_ >> bit_8);
    (f_handle->value)[14] = static_cast<uint8_t>(d_handle->segment_3_ >> bit_16);
    (f_handle->value)[15] = static_cast<uint8_t>(d_handle->segment_3_ >> bit_24);
    return DAL_RETCODE_OK;
}

dal_ret_t
InstanceHandleConverter::ConvertInstanceHandleFromFastddsToDal(const InstanceHandle_t* f_handle,
                                                               dal_instance_handle_t* d_handle)
{
    if (f_handle == nullptr || d_handle == nullptr)
        return DAL_RETCODE_BAD_PARAMETER;
    if ((*f_handle) == HANDLE_NIL) {
        (*d_handle) = DAL_HANDLE_NIL;
        return DAL_RETCODE_OK;
    }
    d_handle->segment_0_ = static_cast<uint32_t>((f_handle->value)[0]) |
                           static_cast<uint32_t>((f_handle->value)[1]) << bit_8 |
                           static_cast<uint32_t>((f_handle->value)[2]) << bit_16 |
                           static_cast<uint32_t>((f_handle->value)[3]) << bit_24;
    d_handle->segment_1_ = static_cast<uint32_t>((f_handle->value)[4]) |
                           static_cast<uint32_t>((f_handle->value)[5]) << bit_8 |
                           static_cast<uint32_t>((f_handle->value)[6]) << bit_16 |
                           static_cast<uint32_t>((f_handle->value)[7]) << bit_24;
    d_handle->segment_2_ = static_cast<uint32_t>((f_handle->value)[8]) |
                           static_cast<uint32_t>((f_handle->value)[9]) << bit_8 |
                           static_cast<uint32_t>((f_handle->value)[10]) << bit_16 |
                           static_cast<uint32_t>((f_handle->value)[11]) << bit_24;
    d_handle->segment_3_ = static_cast<uint32_t>((f_handle->value)[12]) |
                           static_cast<uint32_t>((f_handle->value)[13]) << bit_8 |
                           static_cast<uint32_t>((f_handle->value)[14]) << bit_16 |
                           static_cast<uint32_t>((f_handle->value)[15]) << bit_24;

    return DAL_RETCODE_OK;
}